﻿using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Reflection;

namespace GMS.NET.Web.Components.Shared.Global.Attributes
{
    /// <summary>
    /// api返回数据从响应头取数据
    /// 并返回RestfulResult风格结构体
    /// 该特性并不通用请根据实际场景修改
    /// 避免因使用不当影响系统性能
    /// </summary>
    public class ApiReturnHeaderAttribute : ApiReturnAttribute
    {
        private Type Type { get; set; }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="type">传入需要转化的实体类类型</param>
        public ApiReturnHeaderAttribute(Type type) 
            : base(new MediaTypeWithQualityHeaderValue("application/json"))
        {
            this.Type = type;
        }

        public override async Task SetResultAsync(ApiResponseContext context)
        {
            var apiResult = await context.HttpContext.ResponseMessage!.Content.ReadFromJsonAsync<RestfulResult<object>>();
            var apiHeaders = context.HttpContext.ResponseMessage!.Headers;
            object entityInstance = Activator.CreateInstance(Type)!;
            Type setResultType = typeof(RestfulResult<>).MakeGenericType(Type);
            object resultInstance = Activator.CreateInstance(setResultType)!;
            foreach (var PropertyInfo in Type.GetProperties())
            {
                var getValue = apiHeaders.TryGetValues(PropertyInfo.Name,out var Value);
                if (getValue)
                {
                    if (PropertyInfo.PropertyType == typeof(string))
                    {
                        PropertyInfo.SetValue(entityInstance, Value!.FirstOrDefault());
                    }
                    else if (PropertyInfo.PropertyType == typeof(int))
                    {
                        PropertyInfo.SetValue(entityInstance, Convert.ToInt32(Value!.FirstOrDefault()));
                    }
                }
            }
            setResultType.GetProperty("StatusCode")!.SetValue(resultInstance, apiResult!.StatusCode);
            setResultType.GetProperty("Data")!.SetValue(resultInstance, entityInstance);
            setResultType.GetProperty("Succeeded")!.SetValue(resultInstance, apiResult!.Succeeded);
            setResultType.GetProperty("Timestamp")!.SetValue(resultInstance, apiResult!.Timestamp);
            setResultType.GetProperty("Errors")!.SetValue(resultInstance, apiResult!.Errors);
            setResultType.GetProperty("Extras")!.SetValue(resultInstance, apiResult!.Extras);
            context.Result = resultInstance;
        }
    }
}
